﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.IO;
using System.Configuration;
using RedSand.Web.Mvc;
using RedSand.Web.Language;
using System.Reflection;
using System.Text.RegularExpressions;

namespace RedSand.Site.Controllers
{
    [Authorization]
    public class BaseController : Controller
    {
        protected int UserID
        {
            get 
            {
                int id = Convert.ToInt32(Session["CurrentUserID"]);
                if (User.Identity.IsAuthenticated && id == 0)
                {
                    id = RsDataManager.GetInfo<RedSand.Site.Models.UserInfo>("UserGetInfo", new { UserName = User.Identity.Name }).UserID;
                    Session["CurrentUserID"] = id;
                }
                return id;
            }
            set { Session["CurrentUserID"] = value; }
        }

        public new ActionResult Redirect(string url)
        {
            if (Request.IsAjaxRequest())
            {
                return JavaScript("location='" + url + "'");
            }
            else
            {
                return base.Redirect(url);
            }
        }

        public ActionResult RedirectToLogin()
        {
            return Redirect("/account/login");
        }

        #region message
        protected void AddMessage(string message)
        {
            Session["Message"] += "[msg]" + message;
        }
        protected void AddMessage(Message message)
        {
            switch (message)
            {
                case Message.AccessDenied: AddMessage("Access denial"); break;
                case Message.ContentEmpty: AddMessage("Please enter the content"); break;
                case Message.CreateError: AddMessage("Create error"); break;
                case Message.CreateSuccess: AddMessage("Create success"); break;
                case Message.DataEmpty: AddMessage("Data empty"); break;
                case Message.DeleteError: AddMessage("Delete error"); break;
                case Message.DeleteSuccess: AddMessage("Delete success"); break;
                case Message.DescriptionEmpty: AddMessage("Please enter the description"); break;
                case Message.FileFormatWrong: AddMessage("File type wrong"); break;
                case Message.FileUrlEmpty: AddMessage("Please choose file"); break;
                case Message.ImageUrlEmpty: AddMessage("Please choose image"); break;
                case Message.PageNotFount: AddMessage("Page not found"); break;
                case Message.UpdateError: AddMessage("Update error"); break;
                case Message.UpdateSuccess: AddMessage("Update success"); break;
                case Message.ValueEmpty: AddMessage("Value empty"); break;
            }
        }

        protected ActionResult AjaxMessage(string message)
        {
            return JavaScript("showMessage('" + message + "')");
        }

        public ActionResult AjaxMessage(Message message)
        {
            switch (message)
            {
                case Message.AccessDenied: return AjaxMessage("Access denial"); 
                case Message.ContentEmpty: return AjaxMessage("Please enter the content"); 
                case Message.CreateError: return AjaxMessage("Create error"); 
                case Message.CreateSuccess: return AjaxMessage("Create success"); 
                case Message.DataEmpty: return AjaxMessage("Data empty"); 
                case Message.DeleteError: return AjaxMessage("Delete error"); 
                case Message.DeleteSuccess: return AjaxMessage("Delete success"); 
                case Message.DescriptionEmpty: return AjaxMessage("Please enter the description"); 
                case Message.FileFormatWrong: return AjaxMessage("File type wrong"); 
                case Message.FileUrlEmpty: return AjaxMessage("Please choose file"); 
                case Message.ImageUrlEmpty: return AjaxMessage("Please choose image"); 
                case Message.PageNotFount: return AjaxMessage("Page not found"); 
                case Message.UpdateError: return AjaxMessage("Update error"); 
                case Message.UpdateSuccess: return AjaxMessage("Update success"); 
                case Message.ValueEmpty: return AjaxMessage("Value empty"); 
            }
            return AjaxMessage("");
        }
        protected ActionResult AjaxModelError()
        {
            string msg = "";
            foreach (var value in ModelState.Values)
            {
                foreach (var error in value.Errors)
                {
                    msg += "[msg]" + error.ErrorMessage;
                }
            }
            return JavaScript("showMessage(\"" + HttpUtility.JavaScriptStringEncode(msg) + "\")");
        }
        public MvcHtmlString GetMessage()
        {
            var result = MvcHtmlString.Create((string)Session["Message"] ?? " ");
            Session.Remove("Message");
            return result;
        }
        #endregion

        #region image
        public string UploadImage(string name = "PreviewImage")
        {
            name = name.ToLower();
            try
            {
                if (Request.Files.Count > 0)
                {
                    HttpPostedFileBase fileupload = Request.Files[0];
                    string ext = Path.GetExtension(fileupload.FileName).ToLower();
                    string filefilter = ".jpg|.png|.bmp|.jpeg|.gif";
                    if (!filefilter.Contains(ext))
                    {
                        return "Error: Định dạng file không đúng";
                    }
                    Session[name] = fileupload;
                    return Url.Action("viewimage", "base", new { name = name, rnd = new Random().Next(100, 999) });
                }
                return "Error: Chưa chọn file";
            }
            catch (Exception ex)
            {
                return "Error: " + ex.Message;
            }
        }
        public void ViewImage(string name = "PreviewImage")
        {
            name = name.ToLower();
            Response.Clear();
            HttpPostedFileBase file = (HttpPostedFileBase)Session[name];
            if (file == null)
            {
                Response.ContentType = "image/jpeg";
                System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(200, 30);
                System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp);
                System.Drawing.Font f = new System.Drawing.Font("arial", 15);
                g.FillRectangle(System.Drawing.Brushes.White, 0, 0, 200, 30);
                g.DrawString("Not found", f, System.Drawing.Brushes.DarkBlue, 0, 0);
                bmp.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
            else
            {
                Response.ContentType = file.ContentType;
                int length = file.ContentLength;
                byte[] buffer = new byte[length];
                file.InputStream.Position = 0;
                file.InputStream.Read(buffer, 0, length);
                Response.OutputStream.Write(buffer, 0, length);
            }
            Response.End();
        }
        protected string SaveImage(string oldPath, string name = "PreviewImage")
        {
            name = name.ToLower();
            string path = "/Content/Upload/" + GetControllerName().Replace("Controller", "/");
            HttpPostedFileBase file = (HttpPostedFileBase)Session[name];
            if (file != null)
            {
                try
                {
                    if (!Directory.Exists(Request.PhysicalApplicationPath + path))
                    {
                        Directory.CreateDirectory(Request.PhysicalApplicationPath + path);
                    }
                    string filename = path + DateTime.Now.ToString("ddMMyyyymmhhssff") + Path.GetExtension(file.FileName);
                    file.SaveAs(Request.PhysicalApplicationPath + filename);
                    //Session.Remove(name);
                    DeleteFile(oldPath);
                    return filename;
                }
                catch { }
            }
            return oldPath;
        }

        protected string SaveFile(HttpPostedFileBase file, string path)
        {
            try
            {
                path = '/' + path.TrimEnd('/').TrimStart('/') + "/";
                if (!Directory.Exists(Request.PhysicalApplicationPath + path))
                {
                    Directory.CreateDirectory(Request.PhysicalApplicationPath + path);
                }
                string filename = path + DateTime.Now.ToString("ddMMyyyymmhhssff") + Path.GetExtension(file.FileName);
                file.SaveAs(Request.PhysicalApplicationPath + filename);
                return filename;
            }
            catch 
            {
                return string.Empty;
            }
        }
        protected bool DeleteFile(string path)
        {
            if (string.IsNullOrWhiteSpace(path)) return true;
            try
            {
                FileInfo oldFileInfo = new FileInfo(Request.PhysicalApplicationPath + path);
                if (oldFileInfo.Exists) oldFileInfo.Delete();
                return true;
            }
            catch { }
            return false;
        }
        
        #endregion

        protected string GetControllerName()
        {
            string str = ControllerContext.Controller.ToString();
            return str.Substring(str.LastIndexOf('.') + 1);
        }
        protected string HtmlDecode(string input)
        {
            return HttpUtility.HtmlDecode(HttpUtility.HtmlDecode(input));
        }

        //authorization
        protected override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
            Session["IsChildAction"] = filterContext.IsChildAction;
        }
    }

    public enum Message
    {
        CreateSuccess,
        CreateError,
        UpdateSuccess,
        UpdateError,
        DeleteSuccess,
        DeleteError,
        AccessDenied,
        PageNotFount,
        DataEmpty,
        ValueEmpty,
        DescriptionEmpty,
        ContentEmpty,
        ImageUrlEmpty,
        FileFormatWrong,
        FileUrlEmpty
    }

    public class AjaxOrChildActionAttribute : ActionMethodSelectorAttribute
    {
        public override Boolean IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
        {
            return (controllerContext.HttpContext.Request.IsAjaxRequest() || controllerContext.IsChildAction);
        }
    }
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class MultiButtonAttribute : ActionNameSelectorAttribute
    {
        public string MatchFormKey { get; set; }
        public string MatchFormValue { get; set; }

        public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
        {
            return controllerContext.HttpContext.Request[MatchFormKey] != null &&
                controllerContext.HttpContext.Request[MatchFormKey] == MatchFormValue;
        }
    }
    public class AuthorizationAttribute: AuthorizeAttribute
    {
        private class AllowLink
        {
            public string Link { get; set; }
        }
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (Convert.ToBoolean(httpContext.Session["IsChildAction"])) return true;

            bool loginSuccess = httpContext.User.Identity.IsAuthenticated;

            string action = httpContext.Request.RequestContext.RouteData.Values["action"].ToString().ToLower();
            string controller = httpContext.Request.RequestContext.RouteData.Values["controller"].ToString().ToLower();

            if (controller == "admin" && action == "install") return true;
            if (controller == "account" && action == "login") return true;
            if (controller == "account" && action == "logout") return true;
            if (controller == "home") return true;
            if (controller == "admin" && !loginSuccess) return false;
            if (controller == "action" && httpContext.User.Identity.Name == "admin") return true;

            foreach (var actionItem in RedSand.Site.Models.ActionList.Items.Where(item => item.ParentID != 0))
            {
                Regex reg = new Regex(actionItem.Link);
                if (reg.IsMatch(httpContext.Request.Url.PathAndQuery))
                {
                    if (RsDataManager.ExecuteGetReturn("UserAuthenticate", new { Username = httpContext.User.Identity.Name, Link = actionItem.Link }) == 0)
                    {
                        if (loginSuccess)
                        {
                            string urlRef = (httpContext.Session["UrlReferrer"] ?? "/").ToString();
                            string message = "access denied";
                            if (httpContext.Request.IsAjaxRequest())
                            {
                                httpContext.Response.Redirect("/base/ajaxmessage?message=" + Message.AccessDenied, true);
                            }
                            else
                            {
                                httpContext.Session["Message"] = message;
                                httpContext.Response.Redirect(urlRef, true);
                            }
                            return false;
                        }
                        return false;
                    }
                    break;
                }
            }
            if (!httpContext.Request.IsAjaxRequest())
            {
                httpContext.Session["UrlReferrer"] = httpContext.Request.Url;
            }
            return true;
        }
    }
}
